package main

import (
	"embed"
	"encoding/json"
	"fmt"
	"html/template"
	"io"
	"net/http"

	"github.com/gin-gonic/gin"
	"slices"
)

//go:embed templates/*.gohtml
var tpls embed.FS

type IConfig struct {
	Host        []string `form:"host[]"`
	Path        []string `form:"path[]"`
	Query       []string `form:"query[]"`
	IgnoreHost  string   `form:"ignoreHost"`
	IgnorePath  []string `form:"ignorePath[]"`
	IgnoreQuery []string `form:"ignoreQuery[]"`
}

type InputProp struct {
	Type      string
	RadioName string
	InputName string
	Value     string
}

func view() {
	r := gin.Default()
	r.SetFuncMap(template.FuncMap{
		"toProp": func(inputType, radioName, inputName, value string) InputProp {
			return InputProp{
				Type:      inputType,
				RadioName: radioName,
				InputName: inputName,
				Value:     value,
			}
		},
		"contains": func(key, value string) bool {
			var result bool
			if key == "ignoreHost" {
				result = config.IgnoreHost == value
			}

			if key == "ignorePath[]" {
				result = slices.Contains(config.IgnorePath, value)
			}

			if key == "ignoreQuery[]" {
				result = slices.Contains(config.IgnoreQuery, value)
			}

			return result
		},
	})
	r.LoadHTMLGlob("templates/*")
	r.GET("/", func(c *gin.Context) {
		keys := cache.Keys(keyBase)
		val := cache.MGet(keys)
		keyJSON, _ := json.Marshal(keys)
		valJSON, _ := json.Marshal(val)

		c.HTML(http.StatusOK, "view.gohtml", gin.H{
			"title":  "Main website",
			"keys":   string(keyJSON),
			"values": string(valJSON),
			"config": config,
		})
	})
	cacheHandler(r)
	configHandler(r)
	r.Run(":8080")
}

func configHandler(r *gin.Engine) {
	r.POST("/config", func(c *gin.Context) {
		// 在这种情况下，将自动选择合适的绑定
		if c.ShouldBind(&config) == nil {
			targetEnv = EnvName(config.IgnoreHost)
			makeEnv(targetEnv)
			envIgnoreProxy, envDefaultProxy = makeProxy()
			c.Status(http.StatusOK)
		} else {
			c.JSON(400, gin.H{"status": "bad request"})
		}
	})
}

func cacheHandler(r *gin.Engine) {
	// Route to view all cache entries
	r.GET("/cache", func(c *gin.Context) {
		w := c.Writer
		keys := cache.Keys("proxyTrek")
		val := cache.MGet(keys)
		fmt.Fprint(w, "Value: ", val)
	})

	r.POST("/cache/key", func(c *gin.Context) {
		w := c.Writer
		b := c.Request.Body
		defer c.Request.Body.Close()
		text, _ := io.ReadAll(b)
		key := string(text)
		result, err := cache.Get(key)
		if err != nil {
			fmt.Fprint(w, "Error key: ", err)
			return
		}
		fmt.Println("/cache/value", result)
		fmt.Fprint(w, result)
		c.Status(http.StatusOK)
	})

	// Route to delete a specific cache entry
	r.DELETE("/cache/key", func(c *gin.Context) {
		w := c.Writer
		b := c.Request.Body
		defer c.Request.Body.Close()
		text, _ := io.ReadAll(b)
		key := string(text)
		cache.Del(key)
		fmt.Fprint(w, "Key deleted")
		c.Status(http.StatusNoContent)
	})

	// Route to delete all cache entries
	r.DELETE("/cache", func(c *gin.Context) {
		cache.Clear()
		fmt.Fprint(c.Writer, "All keys deleted")
		c.Status(http.StatusNoContent)
	})
}
